技巧6 使用端口连接容器
Docker容器从一开始就被设计用于运行服务。在大多数情况下,都是这样或那样的 HTTP服务。其中很大一部分是可以使用浏览器访问的Web服务。
这会造成一个问题。如果有多个Docker容器运行在其内部环境中的80端口上,它们将无法全部通过宿主机的80端口进行访问。本技巧将展示如何通过公开和映射容器的端口来管理这一常见场景。
问题
想要将多个运行在同一个端口的Docker容器服务公开到宿主机上。
解决方案
使用Docker的 -p
标志将容器的端口映射到宿主机上。
在这个示例中,我们将使用tutum-wordpress镜像。这里假定我们想在宿主机上运行两个实例来服务不同的博客。
由于此前有很多人想这么做,已经有人准备了任何人都可以获取并启动的镜像。要从外部地址获取镜像,可以使用 docker pull
命令。在默认情况下,镜像将从Docker Hub下载:
$ docker pull tutum/wordpress
如果镜像在你的机器上还不存在,当你试图运行它们时,也会自动获取。
要运行第一个博客,可使用如下命令:
$ docker run -d -p 10001:80 --name blog1 tutum/wordpress
这里的 docker run
命令以守护进程方式( -d
)及发布标志( -p
)运行容器。它指定将宿主机端口( 10001
)映射到容器端口( 80
)上,并赋予该容器一个名称用于识别它( --name blog1 tutum/wordpress
)。
可以对第二个博客做相同操作:
$ docker run -d -p 10002:80 --name blog2 tutum/wordpress
如果现在执行这个命令:
$ docker ps | grep blog
将看到列出的两个博客容器及其端口映射,看起来像下面这样:
$ docker ps | grep blog
9afb95ad3617 tutum/wordpress:latest "/run.sh" 9 seconds ago
➥ Up 9 seconds 3306/tcp, 0.0.0.0:10001->80/tcp blog1
31ddc8a7a2fd tutum/wordpress:latest "/run.sh" 17 seconds ago
➥ Up 16 seconds 3306/tcp, 0.0.0.0:10002->80/tcp blog2
现在可以通过浏览http://localhost:10001和http://localhost:10002来访问自己的容器。
要在完成后删除这些容器(假设不想保留它们——我们将在技巧7中利用它们),可执行下面这个命令:
$ docker rm -f blog1 blog2
如果需要,现在就可以通过管理端口分配在宿主机上运行多个相同的镜像和服务了。
提示
在使用 -p
标志时,很容易忘记哪个端口属于宿主机,哪个端口属于容器。我们可以将它看作是在从左向右读一个句子。用户连接到宿主机( -p
),并从宿主机的端口传递到容器的端口(宿主机端口:容器端口)。如果熟悉SSH的端口转发命令,会发现它们的格式是一样的。
讨论
公开端口是很多Docker用例中至关重要的部分,读者将在本书中多次遇到,尤其是在本书的第四部分,容器相互通信将是日常生活的一部分。
在技巧80中,我们将介绍虚拟网络,并解释它们在幕后做了什么,以及它们如何将宿主机端口指向正确的容器。